<?php

/**
 * This file is part of the Codizer package.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @copyright   Copyright (c) 2010 Advisa (http://www.advisa.fr)
 * @author      Codizer Core Team <team@codizer.org>
 * @package     Codizer
 */

class f_form_Provider extends f_form_Form
{
	private static $instance;

	/**
	 * @return f_form_Provider
	 */
	protected function __construct()
	{
		parent::__construct();
	}

	/**
	 * Get singleton instance
	 *
	 * @return f_form_Provider
	 */
	public static function getInstance()
	{
		if(self::$instance === null)
		{
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Check the submitted form
	 */
	public function isValid()
	{
		// Form values
		$values = $this->params['formValues'];
		
		// Get the current xml description file for the form
		$file = DS.$this->moduleName.DS."forms".DS.$this->documentName.".xml";
		$dirs = array(MODULES_DIR, WEBAPP_MODULES_DIR);
		
		// Check file exist
		foreach($dirs as $dir)
		{
			if(file_exists($dir.$file))
			{
				$xmlFile = $dir.$file;
			}
		}
		
		if(!file_exists($xmlFile))
		{
			throw new Exception("The form xml file is missing");	
		}
		
		// Get Elements formcomponent
		$xmlObject = f_xml_Xpath::getInstance($xmlFile)->fromXpath("fields/formcomponent")->getElements();

		$errors = array();

		// If there are Elements in the xml file
		if(isset($xmlObject[0]))
		{
			// For each elements of the xml file
			foreach($xmlObject as $field)
			{	
				// Get the name of the current field
				$attr_name = $field->getAttributeValue('name');			

				// Get Checkers for current Element
				$checkers = $field->getSubElements('check');
	
				// If there're checkers
				if($checkers != null && count($checkers) > 0)
				{
					// For each checkers
					foreach($checkers as $chercker)
					{
						if(!isset($errors[$attr_name]))
						{
                            if(!isset($values[$attr_name]) && !is_null($field->getAttributeValue('exist')) && $field->getAttributeValue('exist') == true)
                            {
                                continue;
                            }
                            
							// Boolean that let us know if we have to execute the current checker
							$checkerExist = false;
							
							// Get all attributes of current Element
							$attributes = $chercker->getAttributes();
                            if(!isset($values[$attr_name]))
                            {
                                $values[$attr_name] = '';
                            }
							$attributes['value'] = $values[$attr_name];
							
							// Construct the current checker class file path (first of all in codizer core)
							$fileName = "check".ucfirst($attributes['type']).".class.php";
							$file = FRAMEWORK_HOME.DS."form".DS."checkers".DS.$fileName;
							
							// If file exist in codizer core
							if(file_exists($file))
							{
								// Construct the className
								$className = "f_form_checkers_check".ucfirst($attributes['type']);
								
								// Class exist, so must execute it
								$checkerExist = true;
							}
							else	// See if checker exist in user modules
							{	
								
								// Construct the current checker class file path ( in base modules or webapp modules)
                                $file = f_file_Resolver::getModuleFilePath($this->getModuleName(), "forms".DS."checkers".DS.$fileName);

								// If file exist in base modules or webapp modules
								if(!is_null($file))
								{
									// Class exist, so must execute it
									$checkerExist = true;
									
									// Construct the className ( in base modules or webapp modules)
									$prefix = "m_";
									if(strpos($file,DS."webapp".DS) !== false)
									{
										$prefix = "w_";
									}
									$className = $prefix.$this->getModuleName()."_forms_checkers_check".ucfirst($attributes['type']);									
								}
							}
							
							// If checker Exist, proceed it
							if($checkerExist == true)
							{
								// Instantiate current checker and proceed his check method
								$object = new $className($attributes, $values);
								$checkResponse = $object->check();
								
								// If checker return errors
								if($checkResponse !== true)
								{
										// Put errors for current field
										$errors[$attr_name] = $checkResponse;
								}
							}
						}
					}
				}
			}
		}
		
		// Put all errors in form params
		$this->params['errors'] = $errors;

		if(count($this->params['errors']) > 0)
		{
			return false;
		}
		return true;
	}	
}